import socket
import threading
import time
from typing import Dict, Optional
from .auth_manager import AuthManager
from .protocol import Protocol, MessageType
from .sql_handler import SQLHandler

class DatabaseServer:
    """数据库服务器"""
    
    def __init__(self, host: str = "localhost", port: int = 8888):
        self.host = host
        self.port = port
        self.socket = None
        self.running = False
        self.clients: Dict[str, socket.socket] = {}  # session_id -> socket
        
        # 初始化组件
        self.auth_manager = AuthManager()
        self.sql_handler = SQLHandler(self.auth_manager)
        
        print(f"数据库服务器初始化完成")
        print(f"默认用户: admin/admin123 (管理员), user/user123 (普通用户)")
    
    def start(self):
        """启动服务器"""
        try:
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.socket.bind((self.host, self.port))
            self.socket.listen(10)
            self.running = True
            
            print(f"数据库服务器启动成功，监听 {self.host}:{self.port}")
            
            while self.running:
                try:
                    client_socket, client_address = self.socket.accept()
                    print(f"新客户端连接: {client_address}")
                    
                    # 为每个客户端创建处理线程
                    client_thread = threading.Thread(
                        target=self._handle_client,
                        args=(client_socket, client_address)
                    )
                    client_thread.daemon = True
                    client_thread.start()
                    
                except socket.error as e:
                    if self.running:
                        print(f"接受连接时出错: {e}")
                    break
        
        except Exception as e:
            print(f"服务器启动失败: {e}")
        finally:
            self.stop()
    
    def stop(self):
        """停止服务器"""
        self.running = False
        if self.socket:
            self.socket.close()
        print("数据库服务器已停止")
    
    def _handle_client(self, client_socket: socket.socket, client_address):
        """处理客户端连接"""
        session_id = None
        buffer = b""
        
        try:
            while self.running:
                # 接收数据
                data = client_socket.recv(4096)
                if not data:
                    break
                
                buffer += data
                
                # 处理完整的消息
                while len(buffer) >= 4:
                    # 读取消息长度
                    msg_length = int.from_bytes(buffer[:4], byteorder='big')
                    if len(buffer) < 4 + msg_length:
                        break  # 消息不完整，继续接收
                    
                    # 提取完整消息
                    message_data = buffer[:4 + msg_length]
                    buffer = buffer[4 + msg_length:]
                    
                    # 解码并处理消息
                    message = Protocol.decode_message(message_data)
                    if message:
                        response = self._process_message(message, session_id)
                        if response:
                            client_socket.send(response)
                            
                            # 更新会话ID（登录成功后）
                            if message.get("type") == MessageType.LOGIN.value:
                                response_data = Protocol.decode_message(response)
                                if response_data and response_data.get("data", {}).get("success"):
                                    session_id = response_data.get("session_id")
                                    self.clients[session_id] = client_socket
        
        except Exception as e:
            print(f"处理客户端 {client_address} 时出错: {e}")
        finally:
            # 清理会话
            if session_id:
                self.auth_manager.logout(session_id)
                if session_id in self.clients:
                    del self.clients[session_id]
            
            client_socket.close()
            print(f"客户端 {client_address} 断开连接")
    
    def _process_message(self, message: Dict, current_session_id: Optional[str]) -> Optional[bytes]:
        """处理客户端消息"""
        msg_type = message.get("type")
        data = message.get("data", {})
        session_id = message.get("session_id") or current_session_id
        
        try:
            if msg_type == MessageType.LOGIN.value:
                return self._handle_login(data)
            
            elif msg_type == MessageType.LOGOUT.value:
                return self._handle_logout(session_id)
            
            elif msg_type == MessageType.SQL_QUERY.value:
                return self._handle_sql_query(data, session_id)
            
            elif msg_type == MessageType.HEARTBEAT.value:
                return self._handle_heartbeat(session_id)
            
            else:
                # 在_process_message方法中添加新的消息类型处理
                if msg_type == MessageType.ADMIN_COMMAND.value:
                    if not session_id or not self.auth_manager.is_admin(session_id):
                        return Protocol.create_error(403, "需要管理员权限", session_id)
                    return self._handle_admin_command(data, session_id)
                
                # 添加新的处理方法
                # @exception_handler
                # def _handle_admin_command(self, data: Dict, session_id: str) -> bytes:
                #     """处理管理员命令"""
                #     command = data.get("command")
                #
                #     if command == "error_stats":
                #         # 导入错误监控器
                #         from ..utils.error_monitor import error_monitor
                #
                #         # 获取错误统计信息
                #         stats = error_monitor.get_error_stats()
                #         return Protocol.create_response(True, {
                #             "success": True,
                #             "data": stats
                #         }, session_id)
                #
                #     elif command == "error_report":
                #         from ..utils.error_monitor import error_monitor
                #
                #         # 生成完整报告
                #         report = error_monitor.generate_report()
                #         return Protocol.create_response(True, {
                #             "success": True,
                #             "data": report
                #         }, session_id)
                #
                #     else:
                #         return Protocol.create_error(400, "未知的管理员命令", session_id)
        
        except Exception as e:
            print(f"处理消息时发生异常: {e}")  # 添加服务器端日志
            return Protocol.create_error(500, f"服务器内部错误: {str(e)}", session_id)
    
    def _handle_login(self, data: Dict) -> bytes:
        """处理登录请求"""
        username = data.get("username")
        password = data.get("password")
        
        if not username or not password:
            return Protocol.create_error(400, "用户名和密码不能为空")
        
        session_id = self.auth_manager.authenticate(username, password)
        if session_id:
            user_info = self.auth_manager.get_user_info(session_id)
            return Protocol.create_response(True, {
                "success": True,
                "user_info": user_info
            }, "登录成功",session_id)
        else:
            return Protocol.create_error(401, "用户名或密码错误")
    
    def _handle_logout(self, session_id: str) -> bytes:
        """处理登出请求"""
        if self.auth_manager.logout(session_id):
            return Protocol.create_response(True, {
                "success": True,
                "message": "登出成功"
            })
        else:
            return Protocol.create_error(400, "登出失败")
    
    def _handle_sql_query(self, data: Dict, session_id: str) -> bytes:
        """处理SQL查询请求"""
        sql = data.get("sql")
        if not sql:
            return Protocol.create_error(400, "SQL语句不能为空", session_id)
        
        result = self.sql_handler.execute_sql(sql, session_id)
        
        if result.get("success"):
            # 将成功的结果数据打包发送
            return Protocol.create_response(
                True,
                result.get("data", {}),
                "OK",
                session_id
            )
        else:
            return Protocol.create_error(
                result.get("error_code", 500),
                result.get("error", "SQL执行失败"),
                session_id
            )
    
    def _handle_heartbeat(self, session_id: str) -> bytes:
        """处理心跳请求"""
        session = self.auth_manager.validate_session(session_id)
        if session:
            return Protocol.create_response(True, {
                "success": True,
                "server_time": time.time()
            }, session_id)
        else:
            return Protocol.create_error(401, "会话无效", session_id)

def main():
    """服务器主函数"""
    server = DatabaseServer()
    try:
        server.start()
    except KeyboardInterrupt:
        print("\n收到中断信号，正在关闭服务器...")
        server.stop()

if __name__ == "__main__":
    main()